<template>
  <div
    ref="chartRef"
    :style="{
      width: width,
      height: height,
      minHeight: '100px'
    }"
    class="echarts-container"
  ></div>
</template>

<script lang="ts" setup>
import { ref, onMounted, onUnmounted, watch } from "vue"
import * as echarts from "echarts"
import type { EChartsOption } from "echarts"

interface Props {
  options: EChartsOption
  width?: string
  height?: string
  autoResize?: boolean
  theme?: string
}

const props = withDefaults(defineProps<Props>(), {
  width: "100%",
  height: "300px",
  autoResize: true,
  theme: ""
})
const emit = defineEmits(["myClick"])
// 图表实例
let chartInstance: echarts.ECharts | null = null
const chartRef = ref<HTMLElement | null>(null)

// 初始化图表
const initChart = () => {
  if (!chartRef.value) return

  // 销毁已存在的实例
  if (chartInstance) {
    chartInstance.dispose()
  }

  // 创建新实例
  chartInstance = echarts.init(chartRef.value, props.theme)

  // 设置配置项
  if (props.options) {
    chartInstance.setOption(props.options)
  }

  // 监听点击事件
  chartInstance.on("click", (params: any) => {
    emit("myClick", params)
  })
}

// 更新图表尺寸
const resize = () => {
  if (chartInstance) {
    chartInstance.resize()
  }
}

// 监听配置项变化
watch(
  () => props.options,
  newOptions => {
    if (chartInstance && newOptions) {
      chartInstance.setOption(newOptions, true)
    }
  },
  { deep: true }
)

// 监听主题变化
watch(
  () => props.theme,
  () => {
    initChart()
  }
)

// 组件挂载时初始化
onMounted(() => {
  initChart()

  // 添加窗口大小变化监听
  if (props.autoResize) {
    window.addEventListener("resize", resize)
  }
})

// 组件卸载时清理
onUnmounted(() => {
  if (props.autoResize) {
    window.removeEventListener("resize", resize)
  }

  if (chartInstance) {
    chartInstance.dispose()
    chartInstance = null
  }
})

// 暴露方法给父组件
defineExpose({
  // 获取图表实例
  getChartInstance: () => chartInstance,
  // 手动调整大小
  resize,
  // 手动更新配置
  setOption: (options: EChartsOption) => {
    if (chartInstance) {
      chartInstance.setOption(options)
    }
  }
})

defineOptions({
  name: "CommonChart"
})
</script>

<style lang="scss" scoped>
.echarts-container {
  @include flex-center;
  margin: auto;
}
</style>
